# Create your views here.

import csv
import datetime
import traceback
from StringIO import StringIO 

from django.http import HttpResponse, HttpResponseRedirect
from supporters.models import Supporter, Payment, LoadSupporterRun

from django.core.exceptions import ObjectDoesNotExist

import utils


_debug = False

def _summarise_states(statelist):
    state_count = {}
    for s in statelist: 
        if not s in state_count:
            state_count[s] = 0
        state_count[s] += 1
    return state_count


def report_list(request):
    if request.user.is_authenticated():
        page = """<html>
        <body>
        <p><a href="lapsed">Lapsed supporters</a></p>
        <p><a href="summary">Summary</a></p>
        <p><a href="unknown">Unknown</a></p>
        <p><a href="current">Current</a></p>
        <p><a href="everyone">Everyone</a></p>
        <p><a href="update">Manually update supporter states</a></p>
        <p><a href="new">New</a></p>
        <p><a href="loadnew">Load New Supporters</a></p>
        <p><a href="supporterunits">Supporter Units</a></p>
        <p><a href="mysterygift">Mystery Gift</a></p>
        <p><a href="mailchimp">Sync with mailchimp</a></p>
        </body>
        </html>
        """
        return HttpResponse(page)
    else:
        return HttpResponseRedirect('/admin')


def entry(request):
    page = """<html>
    <body>
    <h1>Supporter database</h1>
    <p><a href="admin">Admin</a></p>
    <p><a href="reports">Reports</a></p>  
    </body>
    </html>
    """
    return HttpResponse(page)
    


def summary(request):
    # Create the HttpResponse object with the appropriate CSV header.
    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition'] = 'attachment; filename=summary-%s.csv' % str(datetime.date.today())

    writer = csv.writer(response)

    writer.writerow(["Summary report generated %s" % datetime.date.today()])
    writer.writerow(["Last recorded payment %s" % Payment.objects.all()[0].date])
    writer.writerow([])
    
    supporters = Supporter.objects.all()



    sup_data = []
    for s in supporters:
        if len (s.payment_set.all()):
            last_payment = s.payment_set.all()[0].date
            first_payment = list(s.payment_set.all())[-1].date
        else:
            first_payment = None
            last_payment = None

        sup_data.append((s, first_payment, s.next_payment_date()))

    if _debug:
        print __name__, "found %s supporters" % len(sup_data)
    
    headings = ['Date',
            "Total",
            'Paid Up',
            'New',
            'Total Lapsed',
            'Lapses'
            ]
    writer.writerow(headings)



    as_of_date = datetime.date(day=1,month=2,year=2006)
    prev_month = datetime.date(day=1,month=1,year=2006)

            
                                    
    
    while as_of_date <= datetime.date.today():

        print "report as of", as_of_date, "prev month", prev_month

        # all supporters who joined before asof
        total = len([x for x in sup_data
                     if x[1] and x[1] < as_of_date])
        # all supporters who joined that month
        new = len([x for x in sup_data
                   if x[1] and prev_month <= x[1] < as_of_date])
        # all supporters who joined, but whose next payment date has passed
        total_lapses = len([x for x in sup_data
                            if x[1] and x[2]
                            and x[2] < as_of_date])
        # all supporters whose next payment date is this month
        new_lapse_list = [x
                          for x in sup_data
                          if x[1] and x[2]
                          and prev_month <= x[2] < as_of_date]
        new_lapses = len(new_lapse_list)
        paid_up = total - total_lapses                         
        writer.writerow([as_of_date, total, paid_up, new, total_lapses, new_lapses])

        as_of_date = increase_month(as_of_date)
        prev_month = increase_month(prev_month)

    writer.writerow([])


    today = datetime.date.today()
    as_of_date = datetime.date(day=1, month=today.month, year=today.year)

    current =[x[0] for x in sup_data if x[2] and x[2] >= as_of_date]
    
    #print as_of_date

    writer.writerow([ "breakdown of %s current supporters" % len(current)])
    for payment in Supporter.PAYMENT_CHOICES:
        for freq in Supporter.PAYMENT_FREQUENCY_CHOICES:
            for mtype in Supporter.MEMBER_TYPE_CHOICES:
                
                #print current[0].payment_source
                number = len([x for x in current if
                              x.payment_source == payment[0]
                              and x.payment_frequency == freq[0]
                              and x.member_type == mtype[0]])
                writer.writerow([payment[1], freq[1], mtype[1], number])


    writer.writerow([])
    writer.writerow(['New lapses'])
    writer.writerow(['last', 'first', 'next payment due', 'last payment'])
    for (sup, join, nextp) in new_lapse_list:
        writer.writerow([sup.surname,sup.first_name, nextp, sup.last_payment_date()])
                         
    return response



def increase_month(as_of_date):
    if as_of_date.month == 12:
        as_of_date = datetime.date(day=1,
                                   month=1,
                                   year=as_of_date.year+1)
    else:
        as_of_date = datetime.date(day=1,
                                   month=as_of_date.month+1,
                                   year=as_of_date.year)
                                    
    return as_of_date



def unknown(request):
    # Create the HttpResponse object with the appropriate CSV header.
    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition'] = 'attachment; filename=unknown-%s.csv' % str(datetime.date.today())

    writer = csv.writer(response)
    
    supporters = Supporter.objects.all()
    
    headings = ['id', 
                'surname',
                'first name',
                'email', 
                'membership type', 
                'frequency', 
                'source',
                'last payment date',
                'payment reference'
                
                ]
    writer.writerow(headings)

    for supporter in supporters:
        if supporter.status != 'U':
            continue
        
        writer.writerow([ 
                        supporter.member_id, 
                        supporter.surname,
                        supporter.first_name,
                        supporter.email,
                        supporter.member_type,
                        supporter.payment_frequency,
                        supporter.payment_source,
                        len(supporter.payment_set.all()),
                        supporter.payment_id
                        ])

    return response



def lapsed(request):
    # Create the HttpResponse object with the appropriate CSV header.
    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition'] = 'attachment; filename=lapsed-%s.csv' % str(datetime.date.today())

    writer = csv.writer(response)
    
    supporters = Supporter.objects.all()
    
    headings = ['id', 
                'surname',
                'first name',
                'email', 
                'membership type', 
                'frequency', 
                'source',
                'last payment date',
                'last payment amount',
                'payment reference',
                'first payment date',
                ]
    writer.writerow(headings)

    for supporter in supporters:
        if supporter.status != 'L':
            continue

        payments = list(supporter.payment_set.all())
        if payments:
            last_payment = payments[0].date
            first_payment = payments[-1].date
            last_payment_amount = payments[0].amount
        else:
            last_payment = None 
            first_payment = None
            last_payment_amount = None
        
        writer.writerow([ 
                        supporter.member_id, 
                        supporter.surname,
                        supporter.first_name,
                        supporter.email,
                        supporter.member_type,
                        supporter.payment_frequency,
                        supporter.payment_source,
                        last_payment,
                        last_payment_amount,
                        supporter.payment_id,
                        first_payment
                        
                        ])

    return response

def current(request):
    # Create the HttpResponse object with the appropriate CSV header.
    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition'] = 'attachment; filename=current-%s.csv' % str(datetime.date.today())

    writer = csv.writer(response)
    
    supporters = Supporter.objects.all()
    
    headings = ['id', 
                'surname',
                'first name',
                'email', 
                'membership type', 
                'frequency', 
                'source',
                'last payment date',
                'payment reference',
                'first payment date',
                ]
    writer.writerow(headings)

    for supporter in supporters:
        if supporter.status != 'P':
            continue

        if len (supporter.payment_set.all()):
            last_payment = supporter.payment_set.all()[0].date
            first_payment = list(supporter.payment_set.all())[-1].date
        else:
            first_payment = None
            last_payment = None
        
        writer.writerow([ 
                        supporter.member_id, 
                        supporter.surname,
                        supporter.first_name,
                        supporter.email,
                        supporter.member_type,
                        supporter.payment_frequency,
                        supporter.payment_source,
                        last_payment,
                        supporter.payment_id,
                        first_payment
                        ])

    return response



def update(request):
    Supporter.update_all()

    page = """<html>
    <body>
    I just updated everybody. 
    </body>
    </html>
    """
    return HttpResponse(page)


def everyone(request):
    # Create the HttpResponse object with the appropriate CSV header.
    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition'] = 'attachment; filename=everyone-%s.csv' % str(datetime.date.today())

    writer = csv.writer(response)
    
    supporters = Supporter.objects.all()
    
    headings = ['id', 
                'surname',
                'first name',
                'email', 
                'membership type', 
                'frequency', 
                'source',
                'last payment date',
                'last paymount amount',
                'payment reference',
                'first payment date',
                'state',
                'supporter units',
                'address1',
                'address2',
                'address3',
                'town',
                'county',
                'postcode',
                'country',
                ]
    writer.writerow(headings)

    
    
    for supporter in supporters:

        supporter_units = 0.0
                
        payments = supporter.payment_set.all()
        if len(payments):
            last_payment = payments[0].date
            first_payment = list(payments)[-1].date
            last_payment_amount = payments[0].amount
            
        else:
            last_payment = None
            first_payment = None
            last_payment_amount = None
            
        if last_payment_amount and supporter.status == 'P':
            supporter_units = last_payment_amount
        if supporter.payment_frequency == 'Y': 
            supporter_units = supporter_units / 12.0
        if supporter.status == 'D':
            supporter_units = 0.0
        supporter_units = supporter_units / 500.0
            
        
            
        
        writer.writerow([ 
                        supporter.member_id, 
                        supporter.surname,
                        supporter.first_name,
                        supporter.email,
                        supporter.member_type,
                        supporter.payment_frequency,
                        supporter.payment_source,
                        last_payment,
                        last_payment_amount,
                        supporter.payment_id,
                        first_payment,
                        supporter.status,
                        supporter_units, 
                        supporter.address1,
                        supporter.address2,
                        supporter.address3,
                        supporter.town,
                        supporter.county,
                        supporter.postcode,
                        supporter.country
                        ])

    return response



def new(request):
    # Create the HttpResponse object with the appropriate CSV header.
    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition'] = 'attachment; filename=new-%s.csv' % str(datetime.date.today())

    writer = csv.writer(response)
    
    supporters = Supporter.objects.all()
    
    headings = ['id', 
                'surname',
                'first name',
                'email', 
                'membership type', 
                'frequency', 
                'source',
                'last payment date',
                'last payment amount',
                'payment reference',
                'first payment date',
                ]
    writer.writerow(headings)

    for supporter in supporters:
        if supporter.status != 'P':
            continue

        payments = list(supporter.payment_set.all())
        
        if len(payments) != 1:
            continue

        if payments:
            last_payment = payments[0].date
            first_payment = payments[-1].date
            last_payment_amount = payments[0].amount
        
        writer.writerow([ 
                        supporter.member_id, 
                        supporter.surname,
                        supporter.first_name,
                        supporter.email,
                        supporter.member_type,
                        supporter.payment_frequency,
                        supporter.payment_source,
                        last_payment,
                        last_payment_amount,
                        supporter.payment_id,
                        first_payment
                        
                        ])

    return response

def loadnew(request): 
    supporter_data = utils.get_new_supporters(download=True) 

    previous_run_id = LoadSupporterRun.objects.order_by('-max_id')[0].max_id
    max_id_seen = 0 

    page = StringIO() 
    page.write('<html><body>')

    for sup in supporter_data:
        _handle_new_supporter(sup, page)
        max_id_seen = max(max_id_seen, sup['memberid'])
                
    page.write('</body></html>')

    run = LoadSupporterRun(max_id=max_id_seen)
    run.save()

    return HttpResponse(page.getvalue())


def _handle_new_supporter(sup, page): 
    #page.write(str(sup))

    mid = sup['memberid']
    
    previous_run_id = LoadSupporterRun.objects.order_by('-max_id')[0].max_id

    max_id_seen = 0 

    if mid <= previous_run_id: 
        #page.write("%s ignoring too low" % mid)
        return 

    try: 
        mid = sup['memberid']
        db_sup = Supporter.objects.get(member_id=mid)
        #page.write("%s already in database" % mid)

    except ObjectDoesNotExist: 

        new_sup = Supporter(member_id=mid,
                            first_name=sup['firstname'] or '',
                            surname=sup['surname'] or '',
                            title=sup['title'] or '',
                            authcode=sup['authcode'] or '',
                            address1=sup['address1'] or '', 
                            address2=sup['address2'] or '', 
                            address3=sup['address3'] or '', 
                            town = sup['town'] or '',
                            county=sup['county'] or '',
                            postcode=sup['postcode'] or '', 
                            country=sup['country'] or '', 
                            telephone=sup['telephone'] or '',
                            faxno=sup['faxno'] or '', 
                            heard_about_us= sup['heard_about_us'] or '', 
                            info1=sup['info1'] or '',
                            info2=sup['info2'] or '',
                            info3=sup['info3'] or '',
                            info4=sup['info4'] or '',
                            info5=sup['info5'] or '',
                            group_email_address=sup['group_email_address'] or '', 
                            email=sup['email'] or '',
                            )

        new_sup.save()
        page.write("Created %s" % new_sup)
        page.write('</br>')


def supporterunits(request):
    
    monthly_units = [list(x.payment_set.all()) 
                         for x in Supporter.objects.filter(status='P', payment_frequency='M')]
    monthly_units = sum([x[0].amount for x in monthly_units if len(x) > 0])

    yearly_units = [list(x.payment_set.all()) 
                         for x in Supporter.objects.filter(status='P', payment_frequency='Y')]
    yearly_units = sum([x[0].amount for x in yearly_units if len(x) > 0])


    yearly_units = yearly_units / 12

    units = (monthly_units + yearly_units)/500.0

    page = """<html>
    <body>
    You have %s supporter units. 
    </body>
    </html>
    """ % units

    return HttpResponse(page)
    

def mysterygift(request):
    # Create the HttpResponse object with the appropriate CSV header.
    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition'] = 'attachment; filename=new-%s.csv' % str(datetime.date.today())

    writer = csv.writer(response)

    supporters = Supporter.objects.all()

    headings = ['id', 
                'surname',
                'first name',
                'email', 
                'membership type', 
                'frequency', 
                'source',
                'last payment date',
                'last payment amount',
                'payment reference',
                'first payment date',
                'first payment amount',
                'address1',
                'address2',
                'address3',
                'town',
                'county',
                'postcode', 
                'country',
                ]
    writer.writerow(headings)

    for supporter in supporters:
        if supporter.status != 'P':
            continue

        payments = list(supporter.payment_set.all())

        if len(payments) < 1:
            continue

        if payments:
            last_payment = payments[0].date
            first_payment = payments[-1].date
            last_payment_amount = payments[0].amount
            first_payment_amount = payments[-1].amount
            
        
        magic_date = datetime.date(day=5,month=7,year=2008)
        target = False
        
        if first_payment >= magic_date:
            
            if supporter.payment_frequency == 'M' and first_payment_amount >= 1000:
                target = True
                
            elif supporter.payment_frequency == 'Y' and first_payment_amount >= 12000:
                target = True
        
        elif first_payment < magic_date:
            payment_change = None 
            payments = list(reversed(payments))
            for (i, j) in zip(payments, payments[1:]):
                if i.amount != j.amount:
                    payment_change = i
                    break
            if payment_change and payment_change.date > magic_date: 
                if supporter.payment_frequency == 'M' and last_payment_amount >= 1000:
                    target = True

                elif supporter.payment_frequency == 'Y' and last_payment_amount >= 12000:
                    target = True
            
            
        if not target: 
            continue
        
        writer.writerow([ 
                        supporter.member_id, 
                        supporter.surname,
                        supporter.first_name,
                        supporter.email,
                        supporter.member_type,
                        supporter.payment_frequency,
                        supporter.payment_source,
                        last_payment,
                        last_payment_amount,
                        supporter.get_supporter_id(),
                        first_payment,
                        first_payment_amount,
                        supporter.address1,
                        supporter.address2,
                        supporter.address3,
                        supporter.town,
                        supporter.county,
                        supporter.postcode,
                        supporter.country,

                        ])

    return response
    
def mailchimp(request):

    
    LIST_NAME = 'SupDB'
    
    log = StringIO() 
    print >> log
    print >> log, 'Beginning MailChimp sync'
    
    try: 
        from chimpy import chimpy
        chimp = chimpy.Connection("TODO")
        assert chimp.ping() == "Everything's Chimpy!", "Could not access api"
        print >> log, 'connected to MailChimp'
        
        list_id = test_list = [x for x in chimp.lists() if x['name'] == LIST_NAME].pop()['id']
        existing_members = map(lambda x: x['email'], chimp.list_members(list_id))
        
        print >> log, 'creating interest groups'
        existing_groups = chimp.list_interest_groups(list_id)['groups']
        interest_map = {}
        print existing_groups
        for (code, name) in Supporter.MEMBER_STATUS_CHOICES:
            if name not in existing_groups:
                chimp.list_interest_group_add(list_id, name)
            interest_map[code] = name

        
        print sorted(existing_members)
        
        for supporter in Supporter.objects.all():
            print >> log, 'processing', str(supporter), supporter.email, 
            
            if not supporter.email:
                print >> log, 'no email address'
                continue
            
            if '@' not in supporter.email:
                print >> log, 'no email address'
                continue
                
            if not supporter.status:
                print >> log, 'no status'
                continue

            
            
            if supporter.email not in existing_members:
                try:
                    chimp.list_subscribe(list_id, supporter.email, 
                                            merge_vars={'FNAME':supporter.first_name, 
                                                        'LNAME': supporter.surname,
                                                        'INTERESTS': interest_map[supporter.status],
                                                        'SID': supporter.get_supporter_id()
                                                        }, 
                                            double_optin=False)
                    print >> log, 'subscribed'
                    continue
                except:
                    pass
            
            chimp.list_update_member(list_id, supporter.email, 
                                    merge_vars={'FNAME':supporter.first_name, 
                                                'LNAME': supporter.surname,
                                                'INTERESTS': interest_map[supporter.status],
                                                'SID': supporter.get_supporter_id()
                                                }
                                    )
            print >> log, 'updated'
        
        print >> log, 'sync finished'
        
    except Exception, e:
        print >> log, "Caught exception:", e
        traceback.print_exc(10, log)
        
    page = """<html>
    <body>
    <pre>
    %s
    </pre>
    </body>
    </html>
    """ % log.getvalue()

    return HttpResponse(page)
